#include "stdafx.h"
#include <iostream>
#include <WinSock2.h>
#include <Windows.h>

using namespace std;
#pragma comment(lib, "ws2_32.lib")

SOCKET		g_sServer = INVALID_SOCKET;
HANDLE		g_hNetwork = INVALID_HANDLE_VALUE;
DWORD		g_nTidNetwork = 0;

void CloseNetwork()
{
	if(g_hNetwork != INVALID_HANDLE_VALUE)
	{
		TerminateThread(g_hNetwork, 0);
		g_hNetwork = INVALID_HANDLE_VALUE;
	}

    g_bRun = FALSE;
    if(g_sServer != INVALID_SOCKET)
    {
		closesocket(g_sServer, 0);
		g_sServer = INVALID_SOCKET;
	}
}

BOOL PaserPacket(char *pszMsg, int nSize, SOCKADDR_IN & sRemote)
{
	UCHAR		uCmd = 0;
	char		*pMapName = NULL;
	char		*pText = pszMsg;
	int			nRet = 0;

	MessageBox(NULL, pszMsg, NULL, NULL);
	if(pszMsg == NULL || nSize == 0)
		return FALSE;

	pText = pszMsg;
	pText[nSize] = '\n';
	uCmd = (UCHAR)pText[0];
	pText++;
	switch(uCmd)
	{
	case CMD_GET_MAP:
		{
			pMapName = GetLevelName();
			if(pMapName == NULL || strlen(pMapName) == 0)
				return FALSE;

			nRet = sendto(g_sServer, pMapName, strlen(pMapName), 0, (SOCKADDR*)&sRemote, sizeof(SOCKADDR));
			return nRet;
		}
		break;

	case CMD_SERVER:
		{
			SendCommandToServer(pText);
			nRet = sendto(g_sServer, pszMsg, nSize, 0, (SOCKADDR*)&sRemote, sizeof(SOCKADDR));
			return nRet;
		}
		break;

	case CMD_CLIENT:
		{
			SendCommandToConsole(pText);
			nRet = sendto(g_sServer, pszMsg, nSize, 0, (SOCKADDR*)&sRemote, sizeof(SOCKADDR));
			return nRet;
		}
		break;
	}

	return FALSE;
}

DWORD WINAPI ThreadNetWork(LPVOID lParam)
{
	WSAData wsd;
	char	szRecv[4096] = {0x00};
	int		nRet = 0;
	int		dwSendSize = 0;
	SOCKADDR_IN siRemote, siLocal;

	//select
	fd_set          fd_read;
	struct timeval  timeout;
	timeout.tv_sec = 5;
	timeout.tv_usec = 100;	//标准的Unix系统（BSC）的时间片是100毫秒

	//启动Winsock
	if (WSAStartup(MAKEWORD(2, 2), &wsd) != 0) {
		MessageBox(NULL, "WSAStartup failed.", NULL, NULL);
		cout << "WSAStartup Error = " << WSAGetLastError() << endl;
		return FALSE;
	}

	//创建socket
	g_sServer = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
	if (g_sServer == SOCKET_ERROR) {
		MessageBox(NULL, "socket failed.", NULL, NULL);
		cout << "socket Error = " << WSAGetLastError() << endl;
		return FALSE;
	}

	//设置端口号
	int nPort = 6669;
	siLocal.sin_family = AF_INET;
	siLocal.sin_port = htons(nPort);
	siLocal.sin_addr.S_un.S_addr = htonl(INADDR_ANY);

	//绑定本地地址到socket
	if (bind(g_sServer, (SOCKADDR*)&siLocal, sizeof(siLocal)) == SOCKET_ERROR) {
		MessageBox(NULL, "bind failed.", NULL, NULL);
		cout << "bind Error = " << WSAGetLastError() << endl;
		return 1;
	}

	//for (int i = 0; i < 30; i++)
	while(g_bRun)
	{
		dwSendSize = sizeof(siRemote);

		//select处理
		FD_ZERO(&fd_read);
		FD_SET(g_sServer, &fd_read);
		if (select(g_sServer + 1, &fd_read, NULL, NULL, &timeout) > 0)
		{
			if (FD_ISSET(g_sServer, &fd_read))
			{
				//开始接受数据
				nRet = recvfrom(g_sServer, szRecv, 4096, 0, (SOCKADDR*)&siRemote, &dwSendSize);

				if (nRet == SOCKET_ERROR) {
					MessageBox(NULL, "recvfrom failed.", NULL, NULL);
					cout << "recvfrom Error " << WSAGetLastError() << endl;
					break;
				}
				else if (nRet == 0) {
					MessageBox(NULL, "recvfrom failed 0.", NULL, NULL);
					break;
				}
				else {
					PaserPacket(szRecv, nRet, siRemote);
				}
			}
		}
	}
	//关闭socket连接
	closesocket(g_sServer);

	//清理
	WSACleanup();
	return TRUE;
}

void StartNetWork()
{
	if(g_hNetwork != INVALID_HANDLE_VALUE)
	{
		TerminateThread(g_hNetwork, 0);
		g_hNetwork = INVALID_HANDLE_VALUE;
	}

	g_hNetwork = CreateThread(NULL, NULL, (LPTHREAD_START_ROUTINE)ThreadNetWork, NULL, NULL, &g_nTidNetwork);
	CloseHandle(g_hNetwork);
}